/*
 * common_bit.h
 *
 *  Created on: 2011-5-27
 *      Author: chenl
 */

#ifndef COMMON_BIT_H_
#define COMMON_BIT_H_
#include "common_libnamespace.h"

CHENLIB_NAMESPACE_BEGIN

inline int find_first_bit(const unsigned long *addr, unsigned size)
{
	int d0, d1;
	int res;

	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
	__asm__ __volatile__(
			"xorl %%eax,%%eax\n\t"
			"repe; scasl\n\t"
			"jz 1f\n\t"
			"leal -4(%%edi),%%edi\n\t"
			"bsfl (%%edi),%%eax\n"
			"1:\tsubl %%ebx,%%edi\n\t"
			"shll $3,%%edi\n\t"
			"addl %%edi,%%eax"
			:"=a" (res), "=&c" (d0), "=&D" (d1)
			 :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory");
	return res;
}

inline unsigned long __ffs(unsigned long word)
{
	 __asm__("bsfl %1,%0"
	:"=r" (word)
	:"rm" (word));
	return word;
}

#define SET_BIT(x, n) 	((x) |= (1<<(n)))
#define CLEAR_BIT(x, n) ((x) &= (~(1<<(n))))

CHENLIB_NAMESPACE_END

#endif /* COMMON_BIT_H_ */
